import 'dart:async';
import 'dart:developer' as developer;
import 'package:flutter_webrtc/flutter_webrtc.dart';
import '../config/app_config.dart';
import '../di/service_locator.dart';
import '../../shared/storage/storage_service.dart';
import 'api_service.dart';

/// WebRTC 连接状态
enum WebRtcConnectionState {
  disconnected,
  connecting,
  connected,
  failed,
}

/// WebRTC 服务类
/// 负责管理 WebRTC 连接、媒体流和 SDP 交换
/// 注意：所有 SRS 请求都通过 im-server 代理，不直接连接 SRS 服务器
class WebRtcService {
  final ApiService _apiService;
  final StorageService _storageService;
  
  RTCPeerConnection? _publishPeerConnection;
  RTCPeerConnection? _playPeerConnection;
  MediaStream? _localStream;
  
  // 状态回调
  final StreamController<WebRtcConnectionState> _connectionStateController =
      StreamController<WebRtcConnectionState>.broadcast();
  final StreamController<MediaStream> _remoteStreamController =
      StreamController<MediaStream>.broadcast();
  
  Stream<WebRtcConnectionState> get connectionStateStream =>
      _connectionStateController.stream;
  Stream<MediaStream> get remoteStreamStream => _remoteStreamController.stream;
  
  WebRtcConnectionState _currentState = WebRtcConnectionState.disconnected;
  WebRtcConnectionState get currentState => _currentState;
  
  bool _isMuted = false;
  bool _isVideoEnabled = true;
  
  bool get isMuted => _isMuted;
  bool get isVideoEnabled => _isVideoEnabled;
  
  WebRtcService()
      : _apiService = ServiceLocator().apiService,
        _storageService = ServiceLocator().storageService;
  
  /// 更新连接状态
  void _updateState(WebRtcConnectionState state) {
    if (_currentState != state) {
      _currentState = state;
      _connectionStateController.add(state);
      developer.log('WebRTC状态更新: $state', name: 'WebRtcService');
    }
  }
  
  /// 获取 ICE 服务器配置
  List<Map<String, dynamic>> _getIceServers() {
    // 使用 Google 的公共 STUN 服务器
    return [
      {'urls': 'stun:stun.l.google.com:19302'},
      {'urls': 'stun:stun1.l.google.com:19302'},
      {'urls': 'stun:stun2.l.google.com:19302'},
    ];
  }
  
  /// 获取 WebRTC 配置
  Map<String, dynamic> _getRtcConfiguration() {
    return {
      'iceServers': _getIceServers(),
      'iceCandidatePoolSize': 10,
    };
  }
  
  /// 初始化本地媒体流
  Future<MediaStream> initLocalStream({
    bool audio = true,
    bool video = true,
  }) async {
    try {
      developer.log('开始获取本地媒体流: audio=$audio, video=$video', name: 'WebRtcService');
      
      final constraints = <String, dynamic>{
        'audio': audio,
        'video': video
            ? {
                'width': {'ideal': 1280},
                'height': {'ideal': 720},
              }
            : false,
      };
      
      _localStream = await navigator.mediaDevices.getUserMedia(constraints);
      developer.log('本地媒体流获取成功', name: 'WebRtcService');
      
      return _localStream!;
    } catch (e) {
      developer.log('获取本地媒体流失败: $e', name: 'WebRtcService');
      rethrow;
    }
  }
  
  /// 设置 PeerConnection 的公共事件监听器
  void _setupPeerConnectionListeners(RTCPeerConnection pc) {
    // 监听 ICE 候选
    pc.onIceCandidate = (RTCIceCandidate candidate) {
      developer.log('ICE候选: ${candidate.candidate}', name: 'WebRtcService');
    };
    
    // 监听连接状态
    pc.onIceConnectionState = (state) {
      developer.log('ICE连接状态: $state', name: 'WebRtcService');
      if (state == RTCIceConnectionState.RTCIceConnectionStateConnected ||
          state == RTCIceConnectionState.RTCIceConnectionStateCompleted) {
        _updateState(WebRtcConnectionState.connected);
      } else if (state == RTCIceConnectionState.RTCIceConnectionStateFailed ||
          state == RTCIceConnectionState.RTCIceConnectionStateDisconnected) {
        _updateState(WebRtcConnectionState.failed);
      }
    };
  }
  
  /// 初始化推流连接（通过 im-server 代理发布到 SRS）
  Future<void> initPublishConnection(String streamName) async {
    try {
      developer.log('初始化推流连接: streamName=$streamName', name: 'WebRtcService');
      
      if (_localStream == null) {
        throw Exception('本地媒体流未初始化');
      }
      
      _updateState(WebRtcConnectionState.connecting);
      
      // 创建 PeerConnection
      _publishPeerConnection = await createPeerConnection(_getRtcConfiguration());
      
      // 添加本地流的所有轨道
      for (var track in _localStream!.getTracks()) {
        _publishPeerConnection!.addTrack(track, _localStream!);
      }
      
      // 设置事件监听器
      _setupPeerConnectionListeners(_publishPeerConnection!);
      
      // 创建 Offer
      final offer = await _publishPeerConnection!.createOffer({
        'offerToReceiveAudio': false,
        'offerToReceiveVideo': false,
      });
      
      await _publishPeerConnection!.setLocalDescription(offer);
      
      // 通过 im-server 代理发送到 SRS
      final answerSdp = await _publishToSrs(streamName, offer.sdp!);
      
      // 设置远程描述
      await _publishPeerConnection!.setRemoteDescription(
        RTCSessionDescription(answerSdp, 'answer'),
      );
      
      developer.log('推流连接初始化成功', name: 'WebRtcService');
    } catch (e) {
      developer.log('初始化推流连接失败: $e', name: 'WebRtcService');
      _updateState(WebRtcConnectionState.failed);
      rethrow;
    }
  }
  
  /// 初始化拉流连接（通过 im-server 代理从 SRS 播放）
  Future<void> initPlayConnection(String streamName) async {
    try {
      developer.log('初始化拉流连接: streamName=$streamName', name: 'WebRtcService');
      
      _updateState(WebRtcConnectionState.connecting);
      
      // 创建 PeerConnection
      _playPeerConnection = await createPeerConnection(_getRtcConfiguration());
      
      // 监听远程轨道
      _playPeerConnection!.onTrack = (RTCTrackEvent event) {
        developer.log('收到远程轨道: ${event.track.kind}', name: 'WebRtcService');
        if (event.streams.isNotEmpty) {
          final receivedStream = event.streams[0];
          
          // 关键检查：确保收到的流不是本地流（SRS 回环问题）
          // 通过对象引用比较，而不是 ID 比较
          if (_localStream != null && receivedStream == _localStream) {
            developer.log(
              '⚠️ [WebRtcService] 收到拉流轨道，但流对象是本地流！这是 SRS 回环，拒绝添加到远程流控制器',
              name: 'WebRtcService',
            );
            // 不添加到远程流控制器，直接返回
            return;
          }
          
          developer.log(
            '✅ [WebRtcService] 远程流已添加到控制器 (stream ID: ${receivedStream.id})',
            name: 'WebRtcService',
          );
          _remoteStreamController.add(receivedStream);
        }
      };
      
      // 设置事件监听器
      _setupPeerConnectionListeners(_playPeerConnection!);
      
      // 创建 Offer
      final offer = await _playPeerConnection!.createOffer({
        'offerToReceiveAudio': true,
        'offerToReceiveVideo': true,
      });
      
      await _playPeerConnection!.setLocalDescription(offer);
      
      // 通过 im-server 代理发送到 SRS
      final answerSdp = await _playFromSrs(streamName, offer.sdp!);
      
      // 设置远程描述
      await _playPeerConnection!.setRemoteDescription(
        RTCSessionDescription(answerSdp, 'answer'),
      );
      
      developer.log('拉流连接初始化成功', name: 'WebRtcService');
    } catch (e) {
      developer.log('初始化拉流连接失败: $e', name: 'WebRtcService');
      _updateState(WebRtcConnectionState.failed);
      rethrow;
    }
  }
  
  /// 解析 im-server 返回的 SDP answer
  /// 支持字符串格式（直接 SDP）和 JSON 格式（包含 sdp 字段）
  String _parseSdpAnswer(dynamic responseData) {
    // 如果响应是字符串（SDP格式），直接使用
    if (responseData is String) {
      final sdpString = responseData.trim();
      if (sdpString.startsWith('v=')) {
        return sdpString;
      } else {
        throw Exception('im-server 返回的 SDP 格式无效');
      }
    } else if (responseData is Map) {
      final data = responseData as Map<String, dynamic>;
      if (data['sdp'] != null) {
        return data['sdp'] as String;
      } else {
        throw Exception('im-server 未返回 SDP answer');
      }
    } else {
      throw Exception('im-server 响应格式无效');
    }
  }
  
  /// 通过 im-server 代理推流到 SRS
  /// 注意：不是直接连接 SRS，而是通过 im-server 的 /api/webrtc/rtc/v1/publish 端点
  Future<String> _publishToSrs(String streamName, String sdp) async {
    try {
      developer.log('通过 im-server 发送推流请求: streamName=$streamName', name: 'WebRtcService');
      
      // 通过 im-server 代理，路径为 /api/webrtc/rtc/v1/publish
      // ApiService 的 baseUrl 已经包含 /api 前缀，所以这里只需要 /webrtc/rtc/v1/publish
      final response = await _apiService.post<dynamic>(
        '/webrtc/rtc/v1/publish',
        data: {
          'stream': streamName,
          'sdp': sdp,
        },
      );
      
      if (!response.success) {
        throw Exception('推流请求失败: ${response.message}');
      }
      
      final answerSdp = _parseSdpAnswer(response.data);
      developer.log('推流 SDP 交换成功（通过 im-server）', name: 'WebRtcService');
      return answerSdp;
    } catch (e) {
      developer.log('通过 im-server 推流失败: $e', name: 'WebRtcService');
      rethrow;
    }
  }
  
  /// 通过 im-server 代理从 SRS 拉流
  /// 注意：不是直接连接 SRS，而是通过 im-server 的 /api/webrtc/rtc/v1/play 端点
  Future<String> _playFromSrs(String streamName, String sdp) async {
    try {
      developer.log('通过 im-server 发送拉流请求: streamName=$streamName', name: 'WebRtcService');
      
      // 通过 im-server 代理，路径为 /api/webrtc/rtc/v1/play
      // ApiService 的 baseUrl 已经包含 /api 前缀，所以这里只需要 /webrtc/rtc/v1/play
      final response = await _apiService.post<dynamic>(
        '/webrtc/rtc/v1/play',
        data: {
          'stream': streamName,
          'sdp': sdp,
        },
      );
      
      if (!response.success) {
        throw Exception('拉流请求失败: ${response.message}');
      }
      
      final answerSdp = _parseSdpAnswer(response.data);
      developer.log('拉流 SDP 交换成功（通过 im-server）', name: 'WebRtcService');
      return answerSdp;
    } catch (e) {
      developer.log('通过 im-server 拉流失败: $e', name: 'WebRtcService');
      rethrow;
    }
  }
  
  /// 切换静音状态
  Future<void> toggleMute() async {
    if (_localStream == null) return;
    
    _isMuted = !_isMuted;
    for (var track in _localStream!.getAudioTracks()) {
      track.enabled = !_isMuted;
    }
    
    developer.log('静音状态: $_isMuted', name: 'WebRtcService');
  }
  
  /// 切换视频状态
  Future<void> toggleVideo() async {
    if (_localStream == null) return;
    
    _isVideoEnabled = !_isVideoEnabled;
    for (var track in _localStream!.getVideoTracks()) {
      track.enabled = _isVideoEnabled;
    }
    
    developer.log('视频状态: $_isVideoEnabled', name: 'WebRtcService');
  }
  
  /// 切换摄像头（前置/后置）
  Future<void> switchCamera() async {
    if (_localStream == null) return;
    
    try {
      final videoTrack = _localStream!.getVideoTracks().first;
      await Helper.switchCamera(videoTrack);
      developer.log('切换摄像头成功', name: 'WebRtcService');
    } catch (e) {
      developer.log('切换摄像头失败: $e', name: 'WebRtcService');
    }
  }
  
  /// 通过 im-server 检查流的播放者数量（用于判断对方是否接听）
  Future<int> checkStreamPlayers(String streamName) async {
    try {
      // 通过 im-server 的 /api/webrtc/stream/players 端点查询
      final response = await _apiService.get<Map<String, dynamic>>(
        '/webrtc/stream/players',
        queryParameters: {'stream': streamName},
      );
      
      if (!response.success || response.data == null) {
        return 0;
      }
      
      final players = response.data!['players'] as int? ?? 0;
      return players;
    } catch (e) {
      developer.log('检查流播放者数量失败: $e', name: 'WebRtcService');
      return 0;
    }
  }
  
  /// 清理资源
  Future<void> dispose() async {
    developer.log('清理 WebRTC 资源', name: 'WebRtcService');
    
    // 停止本地流
    if (_localStream != null) {
      for (var track in _localStream!.getTracks()) {
        await track.stop();
      }
      await _localStream!.dispose();
      _localStream = null;
    }
    
    // 关闭 PeerConnection
    await _publishPeerConnection?.close();
    await _playPeerConnection?.close();
    _publishPeerConnection = null;
    _playPeerConnection = null;
    
    _updateState(WebRtcConnectionState.disconnected);
    
    await _connectionStateController.close();
    await _remoteStreamController.close();
  }
}

